<!DOCTYPE html>
<html>

<head>
  <title>Quarkus - Deploying Knative Application to Kubernetes or OpenShift</title>
  <script id="adobe_dtm" src="https://www.redhat.com/dtm.js" type="text/javascript"></script>
  <script src="/assets/javascript/highlight.pack.js" type="text/javascript"></script>
  <META HTTP-EQUIV='Content-Security-Policy' CONTENT="default-src 'none'; script-src 'self' 'unsafe-eval' 'sha256-ANpuoVzuSex6VhqpYgsG25OHWVA1I+F6aGU04LoI+5s=' 'sha256-ipy9P/3rZZW06mTLAR0EnXvxSNcnfSDPLDuh3kzbB1w=' js.bizographics.com https://www.redhat.com assets.adobedtm.com jsonip.com https://ajax.googleapis.com https://www.googletagmanager.com https://www.google-analytics.com https://use.fontawesome.com; style-src 'self' https://fonts.googleapis.com https://use.fontawesome.com; img-src 'self' *; media-src 'self' ; frame-src https://www.googletagmanager.com https://www.youtube.com; frame-ancestors 'none'; base-uri 'none'; object-src 'none'; form-action 'none'; font-src 'self' https://use.fontawesome.com https://fonts.gstatic.com;">
  <META HTTP-EQUIV='X-Frame-Options' CONTENT="DENY">
  <META HTTP-EQUIV='X-XSS-Protection' CONTENT="1; mode=block">
  <META HTTP-EQUIV='X-Content-Type-Options' CONTENT="nosniff">
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <meta name="description" content="Quarkus: Supersonic Subatomic Java">
  <meta name="twitter:card" content="summary_large_image">
  <meta name="twitter:site" content="@QuarkusIO"> 
  <meta name="twitter:creator" content="@QuarkusIO">
  <meta property="og:url" content="https://quarkus.io/guides/getting-started-knative" />
  <meta property="og:title" content="Quarkus - Deploying Knative Application to Kubernetes or OpenShift" />
  <meta property="og:description" content="Quarkus: Supersonic Subatomic Java" />
  <meta property="og:image" content="/assets/images/quarkus_card.png" />
  <link rel="canonical" href="https://quarkus.io/guides/getting-started-knative">
  <link rel="shortcut icon" type="image/png" href="/favicon.ico" >
  <link rel="stylesheet" href="https://quarkus.io/guides/stylesheet/config.css" />
  <link rel="stylesheet" href="/assets/css/main.css" />
  <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.1.0/css/all.css" integrity="sha384-lKuwvrZot6UHsBSfcMvOkWwlCMgc0TaWr+30HWe3a4ltaBwTZhyTEggF5tJv8tbt" crossorigin="anonymous">
  <link rel="alternate" type="application/rss+xml"  href="https://quarkus.io/feed.xml" title="Quarkus">
  <script src="https://quarkus.io/assets/javascript/goan.js" type="text/javascript"></script>
  <script src="https://quarkus.io/assets/javascript/hl.js" type="text/javascript"></script>
</head>

<body class="guides">
  <!-- Google Tag Manager (noscript) -->
  <noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-NJWS5L"
  height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
  <!-- End Google Tag Manager (noscript) -->

  <div class="nav-wrapper">
  <div class="grid-wrapper">
    <div class="width-12-12">
      <input type="checkbox" id="checkbox" />
      <nav id="main-nav" class="main-nav">
  <div class="container">
    <div class="logo-wrapper">
      
        <a href="/"><img src="/assets/images/quarkus_logo_horizontal_rgb_600px_reverse.png" class="project-logo" title="Quarkus"></a>
      
    </div>
    <label class="nav-toggle" for="checkbox">
      <i class="fa fa-bars"></i>
    </label>
    <div id="menu" class="menu">
      <span>
        <a href="/get-started/" class="">Get Started</a>
      </span>
      <span>
        <a href="/guides/" class="active">Guides</a>
      </span>
      <span>
        <a href="/community/" class="">Community</a>
      </span>
      <span>
        <a href="/support/" class="">Support</a>
      </span>
      <span>
        <a href="/blog/" class="">Blog</a>
      </span>
      <span>
        <a href="https://code.quarkus.io" class="button-cta secondary white">Start Coding</a>
      </span>
    </div>
  </div>
      </nav>
    </div>
  </div>
</div>

  <div class="content">
    <div class="guide">
  <div class="width-12-12">
    <h1 class="text-caps">Quarkus - Deploying Knative Application to Kubernetes or OpenShift</h1>
    <div class="hide-mobile toc"><ul class="sectlevel1">
<li><a href="#prerequisites">Prerequisites</a></li>
<li><a href="#solution">Solution</a></li>
<li><a href="#set-up-kubernetes-cluster">Set up Kubernetes Cluster</a></li>
<li><a href="#set-up-nexusoptional">Set up Nexus(Optional)</a></li>
<li><a href="#why-skaffold">Why Skaffold ?</a></li>
<li><a href="#build-and-deploy-application">Build and deploy application</a>
<ul class="sectlevel2">
<li><a href="#cleanup">Cleanup</a></li>
</ul>
</li>
<li><a href="#going-further">Going further</a></li>
</ul></div>
    <div>
      <div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p>This guide covers:</p>
</div>
<div class="paragraph">
<p>The deployment of a serverless application to Kubernetes using <a href="https://knative.dev">Knative</a>.</p>
</div>
<div class="paragraph">
<p>This guide takes as input the application developed in the <a href="building-native-image">native application guide</a>.
So, you should have been able to package your application as a binary executable, copied it in a Docker image and run this image.</p>
</div>
<div class="paragraph">
<p>Depending on whether you are a <em>bare</em> Kubernetes user or an OpenShift user, pick the section you need.
The OpenShift section leverages OpenShift build and route features which are not available in <em>bare</em> Kubernetes.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="prerequisites"><a class="anchor" href="#prerequisites"></a>Prerequisites</h2>
<div class="sectionbody">
<div class="paragraph">
<p>For this guide you need:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>roughly 20 minutes</p>
</li>
<li>
<p>having access to a Kubernetes cluster. Minikube is a valid option.</p>
</li>
<li>
<p>having deployed Knative components on <a href="https://knative.dev/docs/install/knative-with-minikube/">minikube</a></p>
</li>
<li>
<p>having <a href="https://skaffold.dev/">Skaffold</a> CLI on your PATH</p>
</li>
</ul>
</div>
</div>
</div>
<div class="sect1">
<h2 id="solution"><a class="anchor" href="#solution"></a>Solution</h2>
<div class="sectionbody">
<div class="paragraph">
<p>We recommend to follow the instructions in the next sections and build the application step by step. However, you can go right to the completed example.</p>
</div>
<div class="paragraph">
<p>Clone the Git repository: <code>git clone <a href="https://github.com/quarkusio/quarkus-quickstarts.git" class="bare">https://github.com/quarkusio/quarkus-quickstarts.git</a></code>, or download an <a href="https://github.com/quarkusio/quarkus-quickstarts/archive/master.zip">archive</a>.</p>
</div>
<div class="paragraph">
<p>The solution is located in the <code>getting-started-knative</code> directory.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="set-up-kubernetes-cluster"><a class="anchor" href="#set-up-kubernetes-cluster"></a>Set up Kubernetes Cluster</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The following script will start minikube and deploy Knative.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="bash" class="language-bash hljs">./bin/start-minikube.sh
eval $(minikube docker-env) <i class="conum" data-value="1"></i><b>(1)</b></code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td>Make the current Docker context to be that of minikube</td>
</tr>
</table>
</div>
</div>
</div>
<div class="sect1">
<h2 id="set-up-nexusoptional"><a class="anchor" href="#set-up-nexusoptional"></a>Set up Nexus(Optional)</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Nexus is used for caching maven artifacts so that Apache Maven builds are faster.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="bash" class="language-bash hljs">kubectl apply -f k8s/nexus.yaml</code></pre>
</div>
</div>
<div class="paragraph">
<p>Wait for some time to have Nexus initialize and run. You can watch the status via <code>kubectl get pods -w</code>, use <span class="keyseq"><kbd>Ctrl</kbd>+<kbd>c</kbd></span> to terminate the watch.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="why-skaffold"><a class="anchor" href="#why-skaffold"></a>Why Skaffold ?</h2>
<div class="sectionbody">
<div class="paragraph">
<p>As vanilla Kubernetes does not have an easy and developer friendly way to build and deploy application to a local cluster like minikube, without the need to push the image to external container registry. We will be using Skaffold to help us build and deploy the Quarkus application onto Kubernetes.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="build-and-deploy-application"><a class="anchor" href="#build-and-deploy-application"></a>Build and deploy application</h2>
<div class="sectionbody">
<div class="admonitionblock important">
<table>
<tr>
<td class="icon">
<i class="fa icon-important" title="Important"></i>
</td>
<td class="content">
<div class="paragraph">
<p>The container image will not be pushed to a remote container registry, and hence the container image url has to be <code>dev.local</code>, to make Knative deploy it without trying to pull it from external container registry.</p>
</div>
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>To run Knative Quarkus applications, we need to use the multi stage docker build; to build the Quarkus application container image and use it in Kubernetes application deployment.</p>
</div>
<div class="paragraph">
<p>The following command start a one time deployment of Quarkus application and runs starts the Knative service after successful container image build.</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
<div class="paragraph">
<p>If you want to deploy a Quarkus JVM image (using HotSpot), then run the following command before running Skaffold:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="bash" class="language-bash hljs">cp src/main/docker/Dockerfile.jvm Dockerfile</code></pre>
</div>
</div>
<div class="paragraph">
<p>If you want to deploy a Quarkus Native executable image (using GraalVM), then run the following command before running Skaffold:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="bash" class="language-bash hljs">cp src/main/docker/Dockerfile.native Dockerfile</code></pre>
</div>
</div>
<div class="paragraph">
<p>It is very important to note that the Dockerfile in <code>src/main/docker</code> folder has been modified Dockerfiles to support multi stage Docker build.The multi stage Docker build helps in building and containerization of application with single Dockerfile.</p>
</div>
</td>
</tr>
</table>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="bash" class="language-bash hljs">skaffold run</code></pre>
</div>
</div>
<div class="paragraph">
<p>As it will take a few minutes for the build and deployment to be completed you can watch the status using:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="bash" class="language-bash hljs">watch kubectl get pods</code></pre>
</div>
</div>
<div class="paragraph">
<p>A successful Knative service deployment will show the following pods in the current namespace:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="bash" class="language-bash hljs">NAME                                     READY   STATUS    AGE
greeter-deployment-5749cc98fc-gs6zr      2/2     Running   10s</code></pre>
</div>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
The deployment name could differ in your environment.
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>Once the Knative service is successfully running, you can call it using the script <code>./bin/call.sh</code>, which should return a response like <code>hello</code>. Allowing it to idle for approximately 60-65 seconds - that is without any further requests -, you will see it automatically scales down to zero pods.</p>
</div>
<div class="sect2">
<h3 id="cleanup"><a class="anchor" href="#cleanup"></a>Cleanup</h3>
<div class="paragraph">
<p>To delete the application:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="bash" class="language-bash hljs">skaffold delete</code></pre>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="going-further"><a class="anchor" href="#going-further"></a>Going further</h2>
<div class="sectionbody">
<div class="paragraph">
<p>This guide covered the deployment of a Quarkus application as Knative application on Kubernetes
However, there is much more, and the integration with these environments has been tailored to make Quarkus applications execution very smooth.
For instance, the health extension can be used for health check; the configuration support allows mounting the application configuration using config map, the metric extension produces data <em>scrapable</em> by Prometheus and so on.</p>
</div>
</div>
</div>
    </div>
  </div>
</div>

  </div>

  <div class="content project-footer">
  <div class="footer-section">
    <div class="logo-wrapper">
      <a href="/"><img src="/assets/images/quarkus_logo_horizontal_rgb_reverse.svg" class="project-logo" title="Quarkus"></a>
    </div>
  </div>
  <div class="grid-wrapper">
    <p class="grid__item width-3-12">Quarkus is open. All dependencies of this project are available under the <a href='https://www.apache.org/licenses/LICENSE-2.0' target='_blank'>Apache Software License 2.0</a> or compatible license.<br /><br />This website was built with <a href='https://jekyllrb.com/' target='_blank'>Jekyll</a>, is hosted on <a href='https://pages.github.com/' target='_blank'>Github Pages</a> and is completely open source. If you want to make it better, <a href='https://github.com/quarkusio/quarkusio.github.io' target='_blank'>fork the website</a> and show us what you’ve got.</p>

    
      <div class="width-1-12 project-links">
        <span>Navigation</span>
        <ul class="footer-links width-1-12">
          
            <li><a href="/">Home</a></li>
          
            <li><a href="/guides">Guides</a></li>
          
            <li><a href="/community/#contributing">Contribute</a></li>
          
            <li><a href="/faq">FAQ</a></li>
          
            <li><a href="/get-started">Get Started</a></li>
          
        </ul>
      </div>
    
      <div class="width-1-12 project-links">
        <span>Contribute</span>
        <ul class="footer-links width-1-12">
          
            <li><a href="https://twitter.com/quarkusio">Follow us</a></li>
          
            <li><a href="https://github.com/quarkusio">GitHub</a></li>
          
            <li><a href="/security">Security&nbsp;policy</a></li>
          
        </ul>
      </div>
    
      <div class="width-1-12 project-links">
        <span>Get Help</span>
        <ul class="footer-links width-1-12">
          
            <li><a href="https://groups.google.com/forum/#!forum/quarkus-dev">Forums</a></li>
          
            <li><a href="https://quarkusio.zulipchat.com">Chatroom</a></li>
          
        </ul>
      </div>
    

    
      <div class="width-3-12 more-links">
        <span>Quarkus is made of community projects</span>
        <ul class="footer-links">
          
            <li><a href="https://vertx.io/" target="_blank">Eclipse Vert.x</a></li>
          
            <li><a href="https://microprofile.io" target="_blank">Eclipse MicroProfile</a></li>
          
            <li><a href="https://hibernate.org" target="_blank">Hibernate</a></li>
          
            <li><a href="https://netty.io" target="_blank">Netty</a></li>
          
            <li><a href="https://resteasy.github.io" target="_blank">RESTEasy</a></li>
          
            <li><a href="https://camel.apache.org" target="_blank">Apache Camel</a></li>
          
            <li><a href="https://code.quarkus.io/" target="_blank">And many more...</a></li>
          
        </ul>
      </div>
    
  </div>
</div>
  <div class="content redhat-footer">
  <div class="grid-wrapper">
    <span class="licence">
      <i class="fab fa-creative-commons"></i><i class="fab fa-creative-commons-by"></i> <a href="https://creativecommons.org/licenses/by/3.0/" target="_blank">CC by 3.0</a> | <a href="https://www.redhat.com/en/about/privacy-policy">Privacy Policy</a>
    </span>
    <span class="redhat">
      Sponsored by
    </span>
    <span class="redhat-logo">
      <a href="https://www.redhat.com/" target="_blank"><img src="/assets/images/redhat_reversed.svg"></a>
    </span>
  </div>
</div>


  <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js" integrity="sha384-8gBf6Y4YYq7Jx97PIqmTwLPin4hxIzQw5aDmUg/DDhul9fFpbbLcLh3nTIIDJKhx" crossorigin="anonymous"></script>
  <script type="text/javascript" src="/assets/javascript/mobile-nav.js"></script>
  <script type="text/javascript" src="/assets/javascript/scroll-down.js"></script>
  <script src="/assets/javascript/satellite.js" type="text/javascript"></script>
  <script src="https://quarkus.io/guides/javascript/config.js" type="text/javascript"></script>
  <script src="/assets/javascript/search-filter.js" type="text/javascript"></script>
  <script src="/assets/javascript/back-to-top.js" type="text/javascript"></script>
</body>

</html>
